home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / util / ruler_40 / part01 / ruler4.c < prev    next >
C/C++ Source or Header  |  1990-07-08  |  12KB  |  451 lines

  1. /*    RULER
  2.  *
  3.  *      Opens a borderless WorkBench window in which is contained a ruler
  4.  *      for the purpose of aligning or constraining text; the default ruler
  5.  *      is 30 characters with an 8 pixel scale and is intended to help
  6.  *      prevent entering too-long filenames.
  7.  *      
  8.  *      Usage:
  9.  *      
  10.  *          CLI> RUN  RULER  [ size ] [ scale ]
  11.  *      
  12.  *      where `size' is the number of ruler markings, and `scale' is the
  13.  *      width between each marking (a particular font width for example).
  14.  *      
  15.  *    Evoking the command with an argument of "?", such as:
  16.  *
  17.  *        CLI> RULER ?
  18.  *
  19.  *    will print out a help message detailing what values are valid for
  20.  *    your particular Workbench environment.
  21.  *      
  22.  *
  23.  *    The window, of course, can be moved to any convenient location on the
  24.  *    screen, and resized with an invisible resizing gadget found in the
  25.  *    lower right corner.
  26.  *
  27.  *    Version 4.0   29-Dec-1989  (copyright)1989  Chad Netzer and Thad Floryan
  28.  *
  29.  *        Based upon code, idea, and logic from:
  30.  *
  31.  *    Version 1.0   7-Nov-1988   (copyright)1988 Thad Floryan
  32.  *
  33.  *    Revision history:
  34.  *        29-December-1989 - (Ver. 4.0) - Added an offset so that you can
  35.  *            just stick the window on the left edge of the workbench screen,
  36.  *        and it will automatically be lined up with the characters.
  37.  *        Fixed some more minor bugs and rearranged the code a bit.
  38.  *        Added ARP support for those who want it. (CFN)
  39.  *
  40.  *        09-March-1989 - (Ver. 3.1) - Fixed a visual bug so that scale can
  41.  *        no longer be less than eight. (CFN)
  42.  *
  43.  *        06-Dec-1988 - (Ver. 3.0) - Added support for measuring fonts of
  44.  *        varying widths (selectable scale). (CFN)
  45.  *
  46.  *        22-Nov-1988 - (Ver. 2.2) - More adjustments to code, No major
  47.  *            changes.  Program size is slightly smaller.  (CFN)
  48.  *
  49.  *        14-Nov-1988 - (Ver. 2.1) - Fixed a few minor (harmless) bugs.  The
  50.  *        right edge of the ruler is now always redrawn after resizing.
  51.  *        I got rid of that GOTO statement (which in 'C', is considered a
  52.  *        bug. :-)  Version 2.1 now lets you open a ruler to be as low as
  53.  *        12 characters wide, which 2.0 only advertised. (CFN)
  54.  *
  55.  *        13-Nov-1988 - (Ver. 2.0) - I added minor enhancements, most
  56.  *        noteably, the ability to resize the window, and support for 
  57.  *        overscanned screens.    (CFN)
  58.  *
  59.  *
  60.  *    Feel welcome to use this program for any non-commercial purposes or
  61.  *    for your personal learning.  Commercial users are requested to contact
  62.  *    Thad at either:
  63.  *
  64.  *    UUCP:    thad@cup.portal.com (OR) ..!sun!portal!cup.portal.com!thad
  65.  *    BBS:    BBS-JC, 415/961-7250 (300/1200/2400), "Thad Floryan" | "SYSOP"
  66.  *
  67.  *    or Chad at:
  68.  *
  69.  *    UUCP:    chad@ucscb.ucsc.edu    (during school term)
  70.  *    UUCP:    chad@cup.portal.com    (holidays, summer, etc.)
  71.  *    BBS:    BBS-JC, 415/961-7250 (300/1200/2400), "Chad Netzer"
  72.  *
  73.  *
  74.  *    Building instructions (Manx Aztec C):
  75.  *
  76.  *            ************************
  77.  *            ***  Non-ARP Version ***
  78.  *            ************************
  79.  *
  80.  *            cc ruler4
  81.  *            ln ruler4 -lc
  82.  */
  83.  
  84. #include <exec/types.h>
  85. #include <exec/memory.h>
  86. #include <intuition/intuition.h>
  87. #include <intuition/intuitionbase.h>
  88.  
  89. #define NEW(typ)        AllocMem((ULONG)sizeof(typ), MEMF_CLEAR)
  90. #define FREE(p,typ)        FreeMem(p,(ULONG)sizeof(typ))
  91.  
  92. #define    ever (;;)    /* used for infinite loops */
  93.  
  94. #define FATAL 20    /* exit code */
  95. #define WARN  10    /* exit code */
  96. #define NORMAL 0    /* exit code */
  97.  
  98. #define LEFT_OFFSET 3L    /* "dead space" on left side of ruler margin */
  99.  
  100. extern void    *OpenLibrary();
  101. extern void    *OpenWindow();
  102. extern void    *GetMsg();
  103. extern void    *AllocMem();
  104. extern void    ReplyMsg();
  105. void        release_resources();
  106. void        error_exit();
  107.  
  108. struct NewWindow window_def =
  109. {
  110.     240, 0,            /* Initial LeftEdge, TopEdge */
  111.     241, 25,        /* Default pixel-width, pixel-height */
  112.     0, 1,            /* DetailPen, BlockPen */
  113.     CLOSEWINDOW    |    /* IDCMP flags */
  114.     NEWSIZE,
  115.     WINDOWDRAG    |    /* window flags */
  116.     WINDOWDEPTH    |
  117.     WINDOWCLOSE    |
  118.     WINDOWSIZING    |
  119.     SMART_REFRESH    |
  120.     NOCAREREFRESH    |
  121.     BORDERLESS    |
  122.     RMBTRAP,
  123.     NULL,            /* Gadget list */
  124.     NULL,            /* checkmark stuff */
  125.     (UBYTE *)"",        /* window title (to be filled in later) */
  126.     NULL,            /* custom screen pointer */
  127.     NULL,            /* bitmap pointer */
  128.     97 + LEFT_OFFSET, 0,    /* Minwidth, no MinHeight */
  129.     -1, 0,            /* no MaxWidth, MaxHeight */
  130.     WBENCHSCREEN        /* screen type */
  131. };
  132.  
  133. struct Window        *window;
  134. struct RastPort     *rp;
  135. struct Library        *IntuitionBase;
  136. struct Library        *GfxBase;
  137. struct Screen        *screen;
  138. struct IntuiMessage    *sys_message;
  139. ULONG            class;
  140. int            resource_state;
  141.  
  142. char *version = 
  143.     "Text Ruler   V4.0   29-Dec-89 \xA91989 Thad Floryan and Chad Netzer"
  144.     "                                 "; /* padding for "nice" title */
  145.  
  146. char *help_text =                /* help message on startup */
  147.     "\n"
  148.     "%40s\n"
  149.     "Opens a borderless WorkBench window in which is contained a ruler\n"
  150.     "for the purpose of aligning or constraining text; the default ruler\n"
  151.     "is 30 characters with an 8 pixel scale and is intended to help\n"
  152.     "prevent entering too-long filenames.\n\n"
  153.     "Usage:\n\n\t"
  154.     "CLI> RUN  %s  [ size ] [ scale ]\n\n"
  155.     "where `size' is the number of ruler markings, and `scale' is the\n"
  156.     "width between each marking (a particular font width for example).\n\n"
  157.     "`size' must be between 12 and %ld inclusive, and defaults to 30.\n"
  158.     "`scale' cannot be greater than %ld or less than 8.  The default is 8."
  159.     "\n\n";
  160.  
  161. /**********************************************************************/
  162.  
  163. main (argc, argv)
  164.     int    argc;
  165.     char    *argv[];
  166. {
  167.  
  168.     long    fivec;        /* pixel size of five chars    */
  169.     long    fsize;        /* The font size of ruler scale */
  170.     long    max_scale;    /* The max scale size possible  */
  171.     long    max_width;    /* maximum size of ruler    */
  172.     long    w;        /* character width of ruler    */
  173.     long    w_lim;        /* pixel width (w * fsize)    */
  174.     long    x;        /* present window x coordinate    */
  175.     long    y;        /* present window y coordinate    */
  176.     char    buf[5];
  177.  
  178.     long    success;    /* indicates bad return values    */
  179.  
  180.     resource_state = 0;
  181.  
  182. /*
  183.  *    Open Intuition so we can get the screen size limits.
  184.  */
  185.     IntuitionBase = OpenLibrary ("intuition.library", 0L);
  186.     if (IntuitionBase == 0L)
  187.     {
  188.         error_exit("?Cannot open intuition.library\n");
  189.     }
  190.     ++resource_state;
  191.  
  192. /*
  193.  *    Get WorkBench screen information
  194.  */
  195.     screen = NEW(struct Screen);    /* Allocate a buffer for screen data */
  196.     if (screen == 0L)
  197.     {
  198.         release_resources();
  199.         error_exit("?ran out of available memory\n");
  200.     }
  201.     ++resource_state;
  202.     success = GetScreenData(screen, (ULONG) sizeof (struct Screen), 
  203.                 WBENCHSCREEN, 0L);
  204.     if (success == FALSE)
  205.     {
  206.         error_exit();
  207.     }
  208. /*
  209.  *    Set up defaults...
  210.  */
  211.     w = 30L;    /* default ruler is 30 chars for a filename */
  212.     fsize = 8L;    /* default font scale is 8 pixels per char  */
  213.  
  214. /*
  215.  *    find maximum values, adjusted for morerows
  216.  */
  217.     max_width = (screen->Width - LEFT_OFFSET) / 8;
  218.     max_scale = (screen->Width - 2) / 12;
  219.  
  220. /*
  221.  *    Parse command line to obtain requested parameters.
  222.  */
  223.     if (argc > 1)
  224.     {
  225.         if (*argv[1] == '?' ||
  226.         *argv[1] == '-' ||
  227.         *argv[1] == 'h' ||
  228.         *argv[1] == 'H'   )
  229.         {
  230.         printf(    help_text,
  231.             version, argv[0], max_width, max_scale);
  232.  
  233.         release_resources();
  234.         exit (NORMAL);
  235.         }
  236.     }
  237.  
  238.     if (argc > 3)
  239.     {
  240.         printf("?Too many arguments, ``%s ?'' for help\n", argv[0]);
  241.         release_resources();
  242.         exit (WARN);
  243.     }
  244.  
  245.     if ((argc >= 2) && (argc <= 3))
  246.     {
  247.         w = atol(argv[1]);
  248.         if ( w < 12L  ||  w > max_width )
  249.         {
  250.             printf("?`size' must be >= 12 and <= %ld\n", max_width);
  251.             release_resources();
  252.             exit (WARN);
  253.         }
  254.     }
  255.  
  256.     if (argc == 3)
  257.     { 
  258.         fsize = atol(argv[2]);
  259.         if (fsize < 8)
  260.         {
  261.             printf("?Font scale must be at least 8!\n");
  262.         release_resources();
  263.         exit (WARN);
  264.         }
  265.         if (fsize > max_scale)
  266.         {
  267.             printf("?Font size can be NO larger than %ld!\n", max_scale);
  268.             release_resources();
  269.             exit (WARN);
  270.         }
  271.     }
  272.  
  273. /*
  274.  *    Now calculate window sizing and placement parameters and setup title.
  275.  */
  276.     w_lim               = w * fsize;
  277.     window_def.Width    = w_lim + LEFT_OFFSET + 1;
  278.     window_def.LeftEdge = (window_def.Width > 300L) ? 0 : 240;
  279.     window_def.Title    = (UBYTE *)version;
  280.     fivec            = 5L * fsize;
  281. /*
  282.  *    Bomb out if requested ruler size would be larger than the screen.
  283.  */
  284.     if (window_def.Width > screen -> Width )
  285.     {
  286.         error_exit("?Ruler too large for WorkBench screen\n");
  287.     }
  288.  
  289. /*
  290.  *    Open up the graphics library.
  291.  */
  292.     GfxBase = OpenLibrary ("graphics.library", 0L);
  293.     if (GfxBase == 0L)
  294.     {
  295.         error_exit("?Cannot open graphics.library\n");
  296.     }
  297.     ++resource_state;
  298.  
  299. /*
  300.  *    Open the ruler display window.
  301.  */
  302.     window = OpenWindow (&window_def);
  303.     if (window == 0L)
  304.     {
  305.         error_exit("?Cannot open window\n");
  306.     }
  307.     ++resource_state;
  308. /*
  309.  *    Get pointer to raster port.
  310.  */
  311.     rp = window -> RPort;
  312.     SetAPen (rp, 0L);
  313. /*
  314.  *    Use RectFill to blank the window area and set pen for drawing.
  315.  */
  316.     for ever
  317.         {
  318.         SetAPen(rp, 0L);
  319.          RectFill(rp, 0L, 10L, w_lim + LEFT_OFFSET, 24L);
  320. /*
  321.  *    Now set pen to draw.
  322.  */
  323.         SetAPen(rp, 1L);
  324. /*
  325.  *    Because we've used a BORDERLESS window, must fill in some of the
  326.  *    title-/drag-bar space near the lower left where the text starts.
  327.  */
  328.         Move(rp, 28L, 8L);
  329.         Draw(rp, 31L, 8L);
  330. /*
  331.  *    Because we've used a BORDERLESS window, must draw our own line beneath
  332.  *    the title bar to make the bar the same height as the window gadgets.
  333.  *    The `28' is the pixel position just to the right of the close gadget.
  334.  *    The `53' is the pixel width of the depth-arranging gadgets in the upper
  335.  *    right corner of the window.
  336.  */
  337.         Move(rp, 28L,           9L);
  338.         Draw(rp, (w_lim + LEFT_OFFSET - 53L), 9L);
  339.  
  340. /*
  341.  *    When I use the ruler, I like to jam it up against the left hand side of
  342.  *    my workbench screen, so that it to measure something on the CLI.
  343.  *    However, the CLI is offset by a small amount, so I compensate by
  344.  *    starting the "virtual" area of the ruler a little to the right...
  345.  *
  346.  *    Fill in the offset area that is unused.
  347.  */
  348.          RectFill(rp, 0L, 9L, LEFT_OFFSET, 24L);
  349.  
  350. /*
  351.  *    Shorten virtual ruler size by subtracting LEFT_OFFSET from w_lim.
  352.  */
  353. /*         w_lim -= LEFT_OFFSET;*/
  354.  
  355. /*
  356.  *    Draw ruler and text
  357.  */
  358.         for (x = 0L; x < (w_lim + fsize); x += fsize)
  359.         {
  360.         if (x >= w_lim)        /* right edge         */
  361.             {
  362.             x = w_lim;
  363.             y = 10L;
  364.             }
  365.         else if (x == 0L)       y = 10L;    /* left edge         */
  366.         else if ((x % fivec) == 0L)  y = 19L;    /* big tic every 5 chars */
  367.         else                       y = 22L;    /* small tic every char  */
  368.         Move (rp, x + LEFT_OFFSET, y);
  369.         Draw (rp, x + LEFT_OFFSET, 24L);
  370. /*
  371.  *    Label ruler.
  372.  *    The test for position `fivec' (in the Move()) is for centering ``5''
  373.  *    differently than the centering for two-digit numbers.
  374.  */
  375.         if ((x > 0L) && (x < w_lim) && ((x % fivec) == 0L))
  376.         {
  377.             sprintf (buf, "%2ld", (x / fsize));
  378.             Move (rp, (x == fivec) ? (x - 12L + LEFT_OFFSET)
  379.                            : (x -  8L + LEFT_OFFSET), 17L);
  380.             Text (rp, buf, (long) strlen (buf));
  381.         }
  382.         }
  383. /*
  384.  *    Wait for gadget activation.  No busy-/spin-/wait-loops here!
  385.  */
  386.         Wait (1L << window -> UserPort -> mp_SigBit);
  387. /*
  388.  *    Retrieve LAST message in Message Port
  389.  */
  390.         sys_message = GetMsg(window -> UserPort);
  391.         class = sys_message -> Class;
  392.         ReplyMsg(sys_message);
  393. /*
  394.  *    Dump uneeded messages (respond only to the last on LIFO queue).
  395.  */
  396.         while (sys_message = GetMsg(window -> UserPort))
  397.         {
  398.         ReplyMsg(sys_message);
  399.         }
  400.  
  401.         if (class == CLOSEWINDOW)
  402.         {
  403.         release_resources();
  404.         exit (NORMAL);
  405.         }
  406.  
  407.         if (class == NEWSIZE)
  408.         {
  409.         w_lim = (window -> Width) - 1 - LEFT_OFFSET;
  410.         }
  411.     }
  412. }
  413.  
  414. /**********************************************************************
  415.  *
  416.  *    cleanup routine
  417.  *
  418.  *    The ``switch'' on resource_state is to assure we don't attempt to
  419.  *    free something we don't have.  Items are released in the reverse
  420.  *    order they were obtained (by "falling thru" the cases).
  421.  */
  422. void release_resources()
  423. {
  424.     switch (resource_state)
  425.     {
  426.         case 4: CloseWindow (window);
  427.         case 3: CloseLibrary(GfxBase);
  428.         case 2: FREE (screen, struct Screen);
  429.         case 1: CloseLibrary(IntuitionBase);
  430.     }
  431. }
  432.  
  433. /**********************************************************************
  434.  *
  435.  *    error handler
  436.  */
  437. void error_exit(message)
  438.     char    *message;
  439. {
  440.     if (message == 0L)
  441.     {
  442.         printf("Internal failure, exiting gracefully...\n");
  443.     }
  444.     else
  445.     {
  446.         printf(message);
  447.     }
  448.     release_resources();
  449.     exit (FATAL);
  450. }
  451.